package checker;

import util.AST.Program;
import util.AST.Command.FunctionBody;
import util.AST.Command.FunctionDeclaration;
import util.AST.Command.VariableDeclaration;
import util.AST.Expression.BinaryExpression;
import util.AST.Expression.BooleanUnaryExpression;
import util.AST.Expression.IdentifierUnaryExpression;
import util.AST.Expression.NumberUnaryExpression;
import util.AST.Expression.UnaryExpression;
import util.AST.RHS.CallStatementRHS;
import util.AST.RHS.ExpressionRHS;
import util.AST.Statement.AssignStatement;
import util.AST.Statement.BreakStatement;
import util.AST.Statement.CallStatement;
import util.AST.Statement.ContinueStatement;
import util.AST.Statement.IfElseStatement;
import util.AST.Statement.PrintlnStatement;
import util.AST.Statement.ReturnStatement;
import util.AST.Statement.WhileStatement;
import util.AST.Terminal.BooleanValue;
import util.AST.Terminal.Identifier;
import util.AST.Terminal.NumberValue;
import util.AST.Terminal.Operator;
import util.AST.Terminal.Type;

public interface Visitor {

	// Program
	public Object visitProgram(Program prog, Object arg) throws SemanticException;

	// Command
	public Object visitVariableDeclaration(VariableDeclaration decl, Object arg) throws SemanticException;
	public Object visitFunctionDeclaration(FunctionDeclaration decl, Object arg) throws SemanticException;
	public Object visitFunctionBody(FunctionBody decl, Object arg) throws SemanticException;

	// Statment
	public Object visitAssignStatement(AssignStatement stmnt, Object arg) throws SemanticException;
	public Object visitBreakStatement(BreakStatement stmnt, Object arg) throws SemanticException;
	public Object visitCallStatement(CallStatement stmnt, Object arg) throws SemanticException;
	public Object visitContinueStatement(ContinueStatement stmnt, Object arg) throws SemanticException;
	public Object visitIfElseStatement(IfElseStatement stmnt, Object arg) throws SemanticException;
	public Object visitPrintlnStatement(PrintlnStatement stmnt, Object arg);
	public Object visitReturnStatement(ReturnStatement stmnt, Object arg) throws SemanticException;
	public Object visitWhileStatement(WhileStatement stmnt, Object arg) throws SemanticException;

	// RHS
	public Object visitCallStatementRHS(CallStatementRHS rhs, Object arg) throws SemanticException;
	public Object visitExpressionRHS(ExpressionRHS rhs, Object arg) throws SemanticException;

	// Expression
	public Object visitBinaryExpression(BinaryExpression exp, Object arg) throws SemanticException;
	public Object visitUnaryExpression(UnaryExpression exp, Object arg);
	public Object visitIdentifierUnaryExpression(IdentifierUnaryExpression exp, Object arg) throws SemanticException;
	public Object visitNumberUnaryExpression(NumberUnaryExpression exp, Object arg);
	public Object visitBooleanUnaryExpression(BooleanUnaryExpression exp, Object arg);
	
	// Terminal
	public Object visitType(Type term, Object arg);
	public Object visitIdentifier(Identifier term, Object arg) throws SemanticException;
	public Object visitOperator(Operator term, Object arg);
	public Object visitNumberValue(NumberValue term, Object arg);
	public Object visitBooleanValue(BooleanValue term, Object arg);
	
}